package com.djl.mvc.config;

import com.djl.crowd.util.CrowdConstant;
import com.djl.crowd.util.CrowdUtil;
import com.djl.crowd.util.ResultEntity;
import com.djl.crowd.util.exception.LoginAcctAlReadyInUserException;
import com.djl.crowd.util.exception.LoginAcctAlReadyInUserFroUpdateException;
import com.djl.crowd.util.exception.LoginFailedException;
import com.google.gson.Gson;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Author le
 * @Date 2021/11/7 12:54
 * @Version 1.0
 * @desc 基于注解的异常处理
 */
@ControllerAdvice
public class CrowdExceptionResolver {

    /**
     * 保存Admin时如果检测到登录账号重复抛出的异常
     *
     * @param exception
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @ExceptionHandler(value = LoginAcctAlReadyInUserException.class)// 指定要捕获的异常类型
    public ModelAndView resolverLoginFailedException(LoginAcctAlReadyInUserException exception,
                                                     HttpServletRequest request,
                                                     HttpServletResponse response) throws IOException {
        String viewName = "admin-add";
        return commonResolver(viewName, exception, request, response);
    }

    /**
     * 更新Admin时如果检测到登录账号重复抛出的异常
     *
     * @param exception
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @ExceptionHandler(value = LoginAcctAlReadyInUserFroUpdateException.class)// 指定要捕获的异常类型
    public ModelAndView resolverLoginFailedException(LoginAcctAlReadyInUserFroUpdateException exception,
                                                     HttpServletRequest request,
                                                     HttpServletResponse response) throws IOException {
        String viewName = "system-error";
        return commonResolver(viewName, exception, request, response);
    }

    @ExceptionHandler(value = Exception.class)// 指定要捕获的异常类型
    public ModelAndView resolverException(Exception exception,
                                          HttpServletRequest request,
                                          HttpServletResponse response) throws IOException {
        String viewName = "system-error";
        return commonResolver(viewName, exception, request, response);
    }


    /**
     * 登录失败异常
     *
     * @param exception
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @ExceptionHandler(value = LoginFailedException.class)//指定要捕获的异常类型
    public ModelAndView resolverLoginFailedException(LoginFailedException exception,
                                                     HttpServletRequest request,
                                                     HttpServletResponse response) throws IOException {
        String viewName = "admin-login";
        return commonResolver(viewName, exception, request, response);
    }


    /**
     * 空指针异常
     *
     * @param exception
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @ExceptionHandler(value = NullPointerException.class)//指定要捕获的异常类型
//    @ExceptionHandler(value = Exception.class)//指定要捕获的异常类型
    public ModelAndView resolverNullPointerException(NullPointerException exception,
                                                     HttpServletRequest request,
                                                     HttpServletResponse response) throws IOException {
        String viewName = "system-error";
        return commonResolver(viewName, exception, request, response);
    }

    private ModelAndView commonResolver(String viewName,
                                        Exception exception,//实际捕获到的异常
                                        HttpServletRequest request,
                                        HttpServletResponse response) throws IOException {

        //1.判断当前请求类型
        boolean judgeResult = CrowdUtil.judgeRequestType(request);
        //2.是否为ajax
        if (judgeResult) {
            //3.创建ResultEntity对象
            ResultEntity<Object> resultEntity = ResultEntity.failed(exception.getMessage());
            //4.创建Gson对象
            Gson gson = new Gson();
            //5.将ResultEntity对象转为json字符串
            String json = gson.toJson(resultEntity);
            //6.将json字符串作为响应体返回给浏览器
            response.getWriter().write(json);
            //7.第六步已经返回了响应，不再提供ModelAndView对象
            return null;
        }
        //8.不是ajax请求ze创建ModelAndView对象
        ModelAndView mv = new ModelAndView();
        //9.将exception对象存入模型
        mv.addObject(CrowdConstant.ATTR_NAME_EXCEPTION, exception);
        //设置对应的视图名称
        mv.setViewName(viewName);

        return mv;

    }


}
